package com.guocheng.modules.terminals.utils;

import com.guocheng.config.SpringUtil;
import com.guocheng.modules.terminals.mapper.TerminalsMapper;
import com.guocheng.modules.terminals.model.Terminals;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.util.*;

public class TerminalsUtils {

    //使用Restemplate来发送HTTP请求
    private final static RestTemplate restTemplate = new RestTemplate();

    //请求终端信息(从数据库调取)
    public static Terminals terminals;

    //cookies，登陆后cookies存储在这里
    public static List<String> COOKIES = new ArrayList<>();

    /**
     * 初始化登录一次
     */
    static {
        login();
    }

//    public static void main(String[] args) {
//        Terminals terminals1 = new Terminals("http://192.168.3.221","gc@gc.com","gc123456");
//        terminals=terminals1;
//        login(terminals1);
//
//        LinkedMultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
//        body.add("category","employee");
//
//        //get请求拼接参数
//        String s = bodyToGet("/mobile-admin/subjects/list",body);
//
//        //获取请求体
//        HttpEntity httpEntity = TerminalsUtils.getHttpEntity(body);
//
//        //发送请求
//        ResponseEntity<LinkedHashMap> request = request(s, HttpMethod.GET, httpEntity);
//
//        LinkedHashMap body1 = request.getBody();
//        List<Object> data = (List)body1.get("data");
//        List<Emp> emps = TerminalsFiledUtils.to(data, Emp.class);
//        System.out.println(emps);
//
//        System.out.println(request);
//    }

    /**
     * 登录单独写出来
     *
     * @return
     */
    public static boolean login() {
        if (terminals == null) {
            //获取设备终端信息
            TerminalsMapper terminalsMapper = SpringUtil.getBean(TerminalsMapper.class);
            //赋值登录信息
            terminals = terminalsMapper.selectTerminals();
        }
        return login(terminals);
    }

    /**
     * 登录单独写出来
     *
     * @return
     */
    public static boolean login(Terminals t) {
        //参数获取
        LinkedMultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
        body.add("username", t.getUsername());
        body.add("password", t.getPassword());
        //头部信息
        HttpHeaders headers = new HttpHeaders();
        headers.add("user-agent", "Koala Admin");
        //设置返回方式
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        //获取请求体
        HttpEntity httpEntity = new HttpEntity<>(body, headers);

        //发送请求
        ResponseEntity<LinkedHashMap> request =
                null;
        try {
            request = restTemplate.exchange(t.getUrl() + "/auth/login", HttpMethod.POST, httpEntity, LinkedHashMap.class);
        } catch (RestClientException e) {
            throw new RuntimeException("请检查设备状况或连接地址是否正确！");
        }
        int code = (Integer) request.getBody().get("code");
        if (code != 0) {
            throw new RuntimeException("账户名和密码不正确！");
        }
        if (code == -6001) {
            throw new RuntimeException("密码尝试次数过多，请10分钟以后在试！");
        }
        HttpHeaders headers1 = request.getHeaders();
        COOKIES = headers1.get("Set-cookie");
        return true;
    }


    /**
     * 获取请求体
     *
     * @param body 请求参数
     * @return
     */
    public static HttpEntity getHttpEntity(LinkedMultiValueMap<String, Object> body) {
        //设置请求header 为 APPLICATION_JSON
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); //解析from参数
        //放入cookies
        headers.put("Cookie", COOKIES);
        //返回请求体
        return new HttpEntity<>(body, headers);
    }

    /**
     * 通用发送请求
     *
     * @param path       地址
     * @param method     方法
     * @param httpEntity 请求体
     * @return 返回响应体
     */
    public static ResponseEntity<LinkedHashMap> request(String path, HttpMethod method, HttpEntity httpEntity) {
        try {
            //使用 exchange 发送请求，以LinkedHashMap的类型接收返回的数据
            ResponseEntity<LinkedHashMap> response = restTemplate.exchange(terminals.getUrl() + path, method, httpEntity, LinkedHashMap.class);
            //执行一下登录，重新发起请求
            if(response.getStatusCodeValue()!=200) {
                login();
                return restTemplate.exchange(terminals.getUrl() + path, method, httpEntity, LinkedHashMap.class);
            }
            return response;
        } catch (Exception e) {
            //执行一下登录，重新发送请求
            login();
            return restTemplate.exchange(terminals.getUrl() + path, method, httpEntity, LinkedHashMap.class);
        }
    }

    /**
     * get请求时拼接url地址
     *
     * @param url  地址
     * @param body 参数
     * @return
     */
    public static String bodyToGet(String url, LinkedMultiValueMap<String, Object> body) {
        if (body == null) return url;
        Set<Map.Entry<String, List<Object>>> entries = body.entrySet();
        //因为get不能携带body，所以拼接地址栏
        StringBuffer s = new StringBuffer();
        s.append(url);
        s.append('?');

        //抽取参数key和value
        for (Map.Entry<String, List<Object>> entry : entries) {
            String key = entry.getKey();
            List<Object> value = entry.getValue();
            if (value != null && value.size() > 0) {
                for (Object str : value) {
                    s.append(key);
                    s.append('=');
                    s.append(str);
                    s.append('&');
                }
            }
        }
        return s.toString();
    }

}
